package com.yangcangclub.commons.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

/**
 * http 工具类
 */
public class HttpUtils {
    private static Logger logger = LoggerFactory.getLogger(HttpUtils.class);


    public static String doPost(String url, Map<String, String> params) {
        InputStream inputStream = null;
        try {
            HttpClient httpClient = HttpClients.createDefault();
            HttpPost httpRequest = new HttpPost(url);
            logger.info("[HttpPostUrl]:"+url+"[params]:"+JSON.toJSONString(params));
            List<BasicNameValuePair> httpParams = new ArrayList<BasicNameValuePair>();
            Iterator<Entry<String, String>> iter = params.entrySet().iterator();
            while (iter.hasNext()) {
                Map.Entry<String, String> entry = iter.next();
                String key = entry.getKey();
                String val = entry.getValue();
                httpParams.add(new BasicNameValuePair(key, val));
            }

            httpRequest.setEntity(new UrlEncodedFormEntity(httpParams, "UTF-8"));
            HttpResponse httpResponse = httpClient.execute(httpRequest);
            int statusCode = httpResponse.getStatusLine().getStatusCode();
            if (statusCode == 200) {
                inputStream = httpResponse.getEntity().getContent();
            } else {
                logger.error(statusCode+"Error Response: "+ httpResponse.getStatusLine().toString());
                throw new RuntimeException(statusCode+"Error Response: " + httpResponse.getStatusLine().toString());
            }

        }  catch (Exception e) {
            logger.error(e.getMessage(),e);
        }
        return readStream(inputStream,"UTF-8");
    }

    public static String doGet(String url,Map<String, String> params) {
        HttpClient httpClient = HttpClients.createDefault();
        InputStream inputStream = null;
        try {
            if (params != null) {
                String paramStr = "";
                Iterator<Entry<String, String>> iter = params.entrySet().iterator();
                while (iter.hasNext()) {
                    Map.Entry<String, String> entry = iter.next();
                    String key = entry.getKey();
                    key = URLEncoder.encode(key, "UTF-8");
                    String val = entry.getValue();
                    val = URLEncoder.encode(val, "UTF-8");
                    paramStr += paramStr = "&" + key + "=" + val;
                }
                if (!paramStr.equals("")) {
                    paramStr = paramStr.replaceFirst("&", "?");
                    url += paramStr;
                }
            }
            logger.info("[HttpGetUrl]:"+url);
            HttpGet httpRequest = new HttpGet(url);
            HttpResponse  httpResponse = httpClient.execute(httpRequest);
            if (httpResponse.getStatusLine().getStatusCode() != 200) {
                logger.error("Error Response: "+ httpResponse.getStatusLine().toString());
                throw new RuntimeException(httpResponse.getStatusLine().getStatusCode()+"Error Response: " + httpResponse.getStatusLine().toString());
            }
            HttpEntity httpEntity = httpResponse.getEntity();
            inputStream = httpEntity.getContent();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return readStream(inputStream, "UTF-8");
    }

    public static  Map<String, Object> doXmlPost(String url, String param) {
        InputStream inputStream = null;
        try {
            HttpClient httpClient = HttpClients.createDefault();
            HttpPost httpRequest = new HttpPost(url);
            logger.info("[HttpXmlPostUrl]:"+url+"[params]:"+param);

            StringEntity myEntity = new StringEntity(param, "UTF8");
            httpRequest.addHeader("Content-Type", "text/xml");
            httpRequest.setEntity(myEntity);
            HttpResponse httpResponse = httpClient.execute(httpRequest);
            int statusCode = httpResponse.getStatusLine().getStatusCode();
            if (statusCode == 200) {
                inputStream = httpResponse.getEntity().getContent();
            } else {
                logger.error(statusCode+"Error Response: "+ httpResponse.getStatusLine().toString());
                throw new RuntimeException(statusCode+"Error Response: " + httpResponse.getStatusLine().toString());
            }
        }  catch (Exception e) {
            logger.error(e.getMessage(),e);
            throw new RuntimeException("Request with Exception!");
        }

        String result = readStream(inputStream,"UTF-8");
        Map<String, Object> map = XmlUtil.xmlStrToMap(result);

        return map;
    }

    public static  JSONObject doJsonPost(String url, String param) {
        InputStream inputStream = null;
        try {
            HttpClient httpClient = HttpClients.createDefault();
            HttpPost httpRequest = new HttpPost(url);
            logger.info("[HttJsonPostUrl]:"+url+"[params]:"+param);

            StringEntity myEntity = new StringEntity(param, "UTF8");
            httpRequest.addHeader("Content-Type", "application/json");
            httpRequest.setEntity(myEntity);
            HttpResponse httpResponse = httpClient.execute(httpRequest);
            int statusCode = httpResponse.getStatusLine().getStatusCode();
            if (statusCode == 200) {
                inputStream = httpResponse.getEntity().getContent();
            } else {
                logger.error(statusCode+"Error Response: "+ httpResponse.getStatusLine().toString());
                throw new RuntimeException(statusCode+"Error Response: " + httpResponse.getStatusLine().toString());
            }
        }  catch (Exception e) {
            logger.error(e.getMessage(),e);
            throw new RuntimeException("Request with Exception!");
        }

        String result = readStream(inputStream, "UTF-8");

        JSONObject jsonObject = (JSONObject)JsonUtils.parseObject(result, JSONObject.class);
        return jsonObject;
    }

    public static JSONObject doJsonGet(String url,Map<String, String> params) {
        HttpClient httpClient = HttpClients.createDefault();
        InputStream inputStream = null;
        try {
            if (params != null) {
                String paramStr = "";
                Iterator<Entry<String, String>> iter = params.entrySet().iterator();
                while (iter.hasNext()) {
                    Map.Entry<String, String> entry = iter.next();
                    String key = entry.getKey();
                    key = URLEncoder.encode(key, "UTF-8");
                    String val = entry.getValue();
                    val = URLEncoder.encode(val, "UTF-8");
                    paramStr += paramStr = "&" + key + "=" + val;
                }
                if (!paramStr.equals("")) {
                    paramStr = paramStr.replaceFirst("&", "?");
                    url += paramStr;
                }
            }
            logger.info("[HttpGetUrl]:"+url);
            HttpGet httpRequest = new HttpGet(url);
            HttpResponse  httpResponse = httpClient.execute(httpRequest);
            if (httpResponse.getStatusLine().getStatusCode() != 200) {
                logger.error("Error Response: "+ httpResponse.getStatusLine().toString());
                throw new RuntimeException(httpResponse.getStatusLine().getStatusCode()+"Error Response: " + httpResponse.getStatusLine().toString());
            }
            HttpEntity httpEntity = httpResponse.getEntity();
            inputStream = httpEntity.getContent();
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }

        String result = readStream(inputStream, "UTF-8");

        JSONObject jsonObject = (JSONObject)JsonUtils.parseObject(result, JSONObject.class);
        return jsonObject;
    }

    public static String readStream(InputStream stream,String code){
        if (stream==null)return "";
        BufferedReader br=null;
        StringBuilder strResponse = new StringBuilder();
        try {
            String tmp = "";
            br = new BufferedReader(new InputStreamReader(stream,code));
            while ((tmp = br.readLine()) != null) {
                if (tmp.trim().length() > 0) {
                    strResponse.append(tmp.trim());
                }
            }
        } catch (Exception e) {
            logger.error( e.getMessage(),e);
        } finally {
            try {
                if (br != null)
                    br.close();
            } catch (Exception e) {
                logger.error( e.getMessage(),e);
            }
        }
        return strResponse.toString();
    }

}